﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SistemaCenterQuimPost.Control;  //usado para validar la grilla.
using SistemaCenterQuimPost.Reportes; //usado para imprimir la venta.
using SistemaCenterQuimPost.Plantillas; //necesario para obtener fecha, nombre usuario etc,

namespace SistemaCenterQuimPost.UI.PostCajero
{
    public partial class frmRegistrarVentas : SistemaCenterQuimPost.UI.frmGestionProductos
    {

        //----------------ATRIBUTOS--------------------------
                                                            //Atributos usados para obtener datos de la base de datos.   
        private DataSet2TableAdapters.VentasTableAdapter ventasTa;

        private DataSet3 ClienteDs;

        private DataSet3TableAdapters.ClientesTableAdapter clienteTa;

        private DataSet3TableAdapters.MovimientosTableAdapter  movimientosClientesTa;

        private DataSet2TableAdapters.ProductosxVentaTableAdapter productosXventaTa;

        private DataSet2TableAdapters.CajasTableAdapter cajaTa;

        private DataSet2TableAdapters.PedidosTableAdapter pedidoTa;

        private DataSet2TableAdapters.ProductosxPedidoTableAdapter productosXpedidoTa;

        private DataSet2TableAdapters.PostTableAdapter postTa;

        
        private string turno; //almacena el turno actual

        private int codCaja; //almacena el codigo de la caja actual.

       

        
        //----------------CONSTRUCTORES----------------------
        
        public frmRegistrarVentas()
        {
            InitializeComponent();

            ventasTa = new DataSet2TableAdapters.VentasTableAdapter();   //inicializamos adaptadores necesarios para esta interface.
            
            productosXventaTa = new DataSet2TableAdapters.ProductosxVentaTableAdapter();

            ClienteDs = new DataSet3();

            postTa = new DataSet2TableAdapters.PostTableAdapter();

            clienteTa = new DataSet3TableAdapters.ClientesTableAdapter();

            movimientosClientesTa = new DataSet3TableAdapters.MovimientosTableAdapter();

            cajaTa = new DataSet2TableAdapters.CajasTableAdapter();

            pedidoTa = new DataSet2TableAdapters.PedidosTableAdapter();

            productosXpedidoTa = new DataSet2TableAdapters.ProductosxPedidoTableAdapter();

          



            this.turno = ""; //se inicializa el turno con un string arbitrario.

            this.codCaja = 0; //se inicializa el codCaja con un valor arbitrario.

            removerControles();  //se remueve los controles heredados que no necesitamos en esta interface, por diseño no se puede

            posicionarListBox(); //se posiciona los listBox, porque por herencia en el diseño no se puede.

            this.limpiarDatos(); //deja la preparada para nuevos datos.

        }


        //----------------ESTADOS----------------------------

        protected void frmRecibirProductos_Load(object sender, EventArgs e)
        {
            CheckForIllegalCrossThreadCalls = false;  //necesario para trabajar con hilos.

            estEsperandoOperacion(); //estado al comenzar el formulario.

        }

        //redefinido del padre.
        protected override void estEsperandoOperacion() //se redefine para que no cause conflicto. Acá no se usa
        {
            if (refrescarResgProductos) //si hace falta actualizar el refrescarResgProducto se realiza
            {
                ejecutarHiloActualizarResgProductos();

            }

            System.Windows.Forms.Control[] controlesHabilitados = {txtCodBarra, btnBusCodigo, txtDescripcion, btnBusDescripcion, txtCodPedido, btnBusPedido, btnNuevoPedido,btnBuscarCliente, dgvVenta, txtDescuentos, txtAbono, txtObservacion, cboFormaPago, btnProcesar };
            System.Windows.Forms.Control[] controlesDeshabilitados = {lstProductosCodBarra, lstProductosDescripcion, btnImprimir};
            System.Windows.Forms.Control[] controlesVisibles = {lblF2,lblF4,lblF5};
            System.Windows.Forms.Control[] controlesInvisibles = {lstProductosCodBarra, lstProductosDescripcion, lblError, lblF6};

            habilitarControles(controlesHabilitados);
            deshabilitarControles(controlesDeshabilitados);
            visibleControles(controlesVisibles);
            invisibleControles(controlesInvisibles);

            cboFormaPago.SelectedIndex = 0; //Colocamos la forma de pago de contado por defecto.

            errorProvider1.Clear();  //se borran los errores, si habian.

            txtCodBarra.Focus();   //se deja el foco en txtCodBarra

            if (lblDniCliente.Text  != "0")
            {
                cboFormaPago.SelectedIndex = -1;
            }

            estadoDelFormulario = "estEsperandoOperacion";
        }

        private void estEsperandoImpresion()
        {
            System.Windows.Forms.Control[] controlesHabilitados = {btnImprimir};
            System.Windows.Forms.Control[] controlesDeshabilitados = {lstProductosCodBarra, lstProductosDescripcion, txtCodBarra, btnBusCodigo, txtDescripcion, btnBusDescripcion, txtCodPedido,btnBusPedido,btnNuevoPedido,btnBuscarCliente ,dgvVenta, txtDescuentos, txtAbono, txtObservacion,cboFormaPago, btnProcesar};
            System.Windows.Forms.Control[] controlesVisibles = {lblF6};
            System.Windows.Forms.Control[] controlesInvisibles = { lstProductosCodBarra, lstProductosDescripcion, lblError, lblF2, lblF4, lblF5 };

            habilitarControles(controlesHabilitados);
            deshabilitarControles(controlesDeshabilitados);
            visibleControles(controlesVisibles);
            invisibleControles(controlesInvisibles);

            errorProvider1.Clear();  //se borran los errores, si habian.

            txtCodBarra.Focus();   //se deja el foco en txtCodBarra

            estadoDelFormulario = "estEsperandoImpresion";
        }

        //----------------METODOS VARIOS---------------------

        public void verificarCajaAbierta()  //Verifica que exista caja y que esté abierta, es llamado desde el menu.
        {
            try
            {
                int codUltimaCaja = 0;  //almacenará el código de la última caja, si existe.

                codUltimaCaja = Convert.ToInt32(cajaTa.ScalarQueryCaja()); //busca la ultima caja si hay registros.

                cajaTa.FillByNroCaja(centerQuimDs.Cajas, codUltimaCaja); //obtiene todos los datos de la ultima caja


                if (centerQuimDs.Cajas[0].estado == "A") // si la caja está abierta 
                {
                    this.turno = centerQuimDs.Cajas[0].turno; //se establecen el turno y codCaja

                    this.codCaja = codUltimaCaja;  

                    this.Show();  //muestra la interface.

                }

                else   //Si existe caja y está cerrada, informamos que no se procesar ingresos hasta que habra alguna.
                {
                    MessageBox.Show("No existe caja abierta, en la que pueda registrar ventas.", "INFORMES", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    this.Close();
                }
            }

            catch (IndexOutOfRangeException)  //excepcion cuando no encuentra registro en la base de datos caja.
            {
                MessageBox.Show("Aún no se han abierto ninguna caja, por lo tanto no puede registrar ventas.", "INFORMES", MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Close();
            }

            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
        }


        protected virtual void removerControles()   //Eliminar los controles que heredé pero que no los voy a usar.
        {
            this.Controls.Remove(this.lblPrecioCosto);
            this.Controls.Remove(this.txtPrecioCosto);
            this.Controls.Remove(this.lblPrecioVenta);
            this.Controls.Remove(this.txtPrecioVenta);
            this.Controls.Remove(this.lblStockActual);
            this.Controls.Remove(this.txtStockActual);
            this.Controls.Remove(this.lblCantMinima);
            this.Controls.Remove(this.txtCantMinima);
            this.Controls.Remove(this.btnAgregar);
            this.Controls.Remove(this.btnEditar);
            this.Controls.Remove(this.lblEditar);
            this.Controls.Remove(this.lblAgregar);


            this.Controls.Remove(this.lblErrorPCosto);
            this.Controls.Remove(this.lblErrorPVenta);
            this.Controls.Remove(this.lblErrorStockActual);
            this.Controls.Remove(this.lblErrorCantMin);
        }

        private void posicionarListBox()  //usado para colocar a los lstBox en su lugar, ya que por herencia en t.Diseño no se puede.
        {
            lstProductosCodBarra.Location = new Point(34, 65);
            lstProductosDescripcion.Location = new Point(270, 65);
        }

        protected virtual void limpiarDatos()          //limpia la interface para iniciar una nueva venta.
        {
            txtCodBarra.Text = "";
            txtDescripcion.Text = "";
            lblDniCliente.Text = "0";
            lblNombreCliente.Text = "CONSUMIDOR FINAL";
            txtCodPedido.Text = "";
            dgvVenta.Rows.Clear();
            txtSubtotal.Text = "0";
            txtDescuentos.Text = "0";
            txtTotal.Text = "0";
            txtAbono.Text = "0";
            txtVuelto.Text = "0";
            txtObservacion.Text = "";
        }

        //se redefine desde el padre
        protected override void cargarProductoPorCodigo(string unCodBarra) //busca producto con codigo de barra único (una coincidencia) encontrado en el oHiloFiltrarCodBarra y lo carga en el dgvProductos
        {
            try
            {
                //(ALE)HACER EL FILL O COMO LO LLAMES ACA ABAJO
                //ProductosTa.FillByProductos1(centerQuimDs,unCodBarra);
                productosTa.FillByCodigo(centerQuimDs.Productos, unCodBarra);

                if ((centerQuimDs.Productos[0].tipo == "T") || ((centerQuimDs.Productos[0].tipo == "D") & (centerQuimDs.Productos[0].litrosEnvase > 0))) //si el producto es terminado o disuelto para vender por cantidad. El stock es del producto actual. Se colorea la cantidad en gris y se pone solo lectura el kgLtrs.
                {
                    dgvVenta.Rows.Add(centerQuimDs.Productos[0].stockActual,centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, 1, 0, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 1 y kiloLtrs 0

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[5].ReadOnly = true; //el kgLtrs se hace solo lectura

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[4].Style.BackColor = Color.LightGray; //cantidad es gris

                }
                else
                {
                    if (centerQuimDs.Productos[0].tipo == "B") //si el producto es base. El stock es del producto actual.
                    {
                        dgvVenta.Rows.Add(centerQuimDs.Productos[0].stockActual, centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, 0, 1, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 0 y kiloLtrs 1

                    }
                    else //si el producto es disuelto para vender por granel. El stock es del producto base.
                    {
                        
                        string resgDescripcion = centerQuimDs.Productos[0].descripcion; //Para obtener el stock de la base, se debe reguardar la descripcion del producto actual, para luego volver a consultar y rellenar la fila.

                        string resgBaseDescripcion = centerQuimDs.Productos[0].baseDescripcion;

                        productosTa.FillByNombre(centerQuimDs.Productos, resgBaseDescripcion);

                        string stock = centerQuimDs.Productos[0].stockActual.ToString();

                        productosTa.FillByNombre(centerQuimDs.Productos, resgDescripcion);

                        dgvVenta.Rows.Add(stock, centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, 0, 1, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 0 y kiloLtrs 1

                    }

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[4].ReadOnly = true; //la cantidad se hace solo lectura
                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[5].Style.BackColor = Color.LightGray; //kgLtrs es gris
                }

                verificarStock(); //formatea la fila correspondiente al producto ingresado, puede ser blanco, amarillo o rojo.
                                    //los prodcutos disueltos para venta por granel se colorea segun el estado de stock en su base.

                txtCodBarra.Text = ""; //se borra el txtCodBarra y Descripción
                txtDescripcion.Text = ""; 

                this.calcularSubTotalVenta();

            }
            catch (IndexOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }
        }

        private void verificarStock() //cuando se carga un producto a la grilla o se modifica algo, se verifica el stock, de esta manera sabemos si podemos vender. Blanco=normal, amarillo=Minimo, rojo=sinStock.
        {
            if ((centerQuimDs.Productos[0].tipo == "D") & (centerQuimDs.Productos[0].litrosEnvase == 0)) //producto disuelto vendido por granel
            {
                productosTa.FillByNombre(centerQuimDs.Productos, centerQuimDs.Productos[0].baseDescripcion.ToString()); //se cambia la referencia del producto al de su base.

            }

            if (centerQuimDs.Productos[0].stockActual <= centerQuimDs.Productos[0].cantidadMinima)  //coloca en color amarillo si el producto se encuentra con cantidad mínima.
            {
                dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[0].Style.BackColor = Color.LightYellow;
            }


            if (centerQuimDs.Productos[0].stockActual <= 0) //coloca en color rojo si el producto se encuentra sin stock.
            {
                dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[0].Style.BackColor = Color.LightPink;
            }
        }

        protected override void cargarProductoPorDescripcion(string unaDescripcion)  //busca el producto por descripción en la base de datos y lo carga en el dgvProductos.
        {
            try
            {
                //(ALE)HACER EL FILL O COMO LO LLAMES ACA ABAJO
                //ProductosTa.FillByProductos1(centerQuimDs,unCodBarra);
                productosTa.FillByNombre(centerQuimDs.Productos, unaDescripcion);

                if ((centerQuimDs.Productos[0].tipo == "T") || ((centerQuimDs.Productos[0].tipo == "D") & (centerQuimDs.Productos[0].litrosEnvase > 0))) //si el producto es terminado o disuelto para vender por cantidad. El stock es del producto actual. Se colorea la cantidad en gris y se pone solo lectura el kgLtrs.
                {
                    dgvVenta.Rows.Add(centerQuimDs.Productos[0].stockActual, centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, 1, 0, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 1 y kiloLtrs 0

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[5].ReadOnly = true; //el kgLtrs se hace solo lectura

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[4].Style.BackColor = Color.LightGray; //cantidad es gris

                }
                else
                {
                    if (centerQuimDs.Productos[0].tipo == "B") //si el producto es base. El stock es del producto actual.
                    {
                        dgvVenta.Rows.Add(centerQuimDs.Productos[0].stockActual, centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, 0, 1, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 0 y kiloLtrs 1

                    }
                    else //si el producto es disuelto para vender por granel. El stock es del producto base.
                    {

                        string resgDescripcion = centerQuimDs.Productos[0].descripcion; //Para obtener el stock de la base, se debe reguardar la descripcion del producto actual, para luego volver a consultar y rellenar la fila.

                        string resgBaseDescripcion = centerQuimDs.Productos[0].baseDescripcion;

                        productosTa.FillByNombre(centerQuimDs.Productos, resgBaseDescripcion);

                        string stock = centerQuimDs.Productos[0].stockActual.ToString();

                        productosTa.FillByNombre(centerQuimDs.Productos, resgDescripcion);

                        dgvVenta.Rows.Add(stock, centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, 0, 1, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 0 y kiloLtrs 1

                    }

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[4].ReadOnly = true; //la cantidad se hace solo lectura
                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[5].Style.BackColor = Color.LightGray; //kgLtrs es gris
                }

                verificarStock();//formatea la fila correspondiente al producto ingresado, puede ser blanco, amarillo o rojo.
                            //los prodcutos disueltos para venta por granel se colorea segun el estado de stock en su base.

                txtCodBarra.Text = ""; //se borra el txtCodBarra y Descripción
                txtDescripcion.Text = ""; 

                this.calcularSubTotalVenta();

            }
            catch (IndexOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }

        }

        protected override void resguardarProductoActual() //esta operación aunque se hereda, se deja vacia.
        {

        }

        private void dgvVenta_CellValueChanged(object sender, DataGridViewCellEventArgs e) //captura los cambios en la grilla.
        {
            
            calcularSubTotalVenta();

        }
        protected virtual void calcularSubTotalVenta()
        {
            Double subTotal = 0;

            this.validarGrilla(); //valida que la grilla donde existe selección, sea válida

            this.validarGrillaSinItems(); //valida que la grilla tenga fila o selecciones

            if (errorProvider1.GetError(dgvVenta) == "")  //si la grilla no tiene errores se procede a obtener el subtotal
            {
                foreach (DataGridViewRow row in dgvVenta.Rows)
                {
                    if ((bool)row.Cells[8].Value)
                    {
                        Double subtotalRow = 0; //subtotal de fila

                        subtotalRow = Convert.ToDouble(row.Cells[3].Value) * Convert.ToDouble(row.Cells[4].Value) + Convert.ToDouble(row.Cells[3].Value) * Convert.ToDouble(row.Cells[5].Value);  //precioUni*Cant + precioUni*Kg.Ltrs;

                        Double descuento = 0; //almacenará el subtotal con el descuento calculado.
                        
                        descuento = Math.Round((Convert.ToDouble(row.Cells[6].Value) / 100)*subtotalRow,2); //no puede haber divisiones por cero nunca.

                        row.Cells[7].Value = Math.Round(Convert.ToDouble(subtotalRow-descuento), 2);

                        subTotal += Convert.ToDouble(row.Cells[7].Value); //acumula el subtotal general.
                    }
                    
                }

                txtSubtotal.Text = subTotal.ToString();

            }

        }


        protected virtual void validarGrilla() //recorre todo el dataGride y verifica que los datos se encuentren correctos, si alguno está incorrecto los pinta de blanco
        {
            bool grillaSinError = true;  //inicializa el booleano que controla si el dgvProductos tiene al menos un error.
         
            foreach (DataGridViewRow row in dgvVenta.Rows)
            {
                if (((bool)row.Cells[8].Value) && (((new ValidarDatos().validarNaturales("Fila:", Convert.ToString(row.Cells[4].Value))) != "") || ((new ValidarDatos().validarRealesPositvos("Fila:", Convert.ToString(row.Cells[5].Value))) != "") || ((new ValidarDatos().validarPorcentaje("Fila:", Convert.ToString(row.Cells[6].Value))) != "")))
                {
                    grillaSinError = false;  //si la fila está tildada y tiene error en la cantidad o en kilo/ltrs se pone a falso
                }

            }


            if (grillaSinError)
            {
                errorProvider1.SetError(dgvVenta, "");
            }
            else
            {
                errorProvider1.SetError(dgvVenta, "Algunos de los campos cantidad en la grilla no contiene datos válidos.");
            }
            

        }

        private void dgvVenta_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e) //captura la eliminación de fila de la grilla
        {
            if ((dgvVenta.Rows.Count > 0) & (estadoDelFormulario == "estEsperandoOperacion")) 
            {
                calcularSubTotalVenta();
            }
        }

        protected virtual void txtSubtotal_TextChanged(object sender, EventArgs e) //captura el cambio de valor en txtSubtotal
        {
            calcularTotalVenta();   //si hay un cambio en el subtotal, ya sea porque se agrega, modifica o elimina una fila de productos
            calcularVuelto();
            
        }


        protected virtual void txtDescuentos_TextChanged(object sender, EventArgs e) //captura el cambio de valor en txtSubtotal
        {
            calcularTotalVenta();  //si hay un cambio en descuento, se debe recalcular el total de venta y el vuelto.
            calcularVuelto();
        }

        protected virtual void txtAbono_TextChanged(object sender, EventArgs e) //captura el cambio de valor en txtSubtotal
        {
            calcularVuelto();  //Si hay un cambio en abono, se debe recalcular el vuelto.
        }

        protected void calcularTotalVenta() //obtiene el total de venta, basado en el subtotal-descuento
        {
            try
            {
                if (txtDescuentos.Text != "")
                {
                    Double descuento = 0; //almacenará el descuento calculado del total general.

                    descuento = Math.Round(((Convert.ToDouble(txtDescuentos.Text)/100) * (Convert.ToDouble(txtSubtotal.Text))),2); //no puede haber divisiones por cero nunca.
 
                    txtTotal.Text = Convert.ToString( Math.Round((Convert.ToDouble(txtSubtotal.Text) - descuento),2));
                }

                errorProvider1.SetError(txtDescuentos, "");
            }
            catch (FormatException) //esta excepción puede ocurrir cuando intenta convertir el descuento en double y no es un valor válido. En este caso no se toma el descuento.
            {

                errorProvider1.SetError(txtDescuentos, "Descuentos: el valor debe ser numérico o cero.");
                txtTotal.Text = txtSubtotal.Text;
            }
        }

        protected virtual void calcularVuelto() //calcula el vuelto, basado en abono-venta.
        {
            try
            {
                if (txtAbono.Text != "")
                {
                    txtVuelto.Text = Convert.ToString(Convert.ToDouble(txtAbono.Text) - Convert.ToDouble(txtTotal.Text));

                }
                else
                {
                    txtVuelto.Text = "0";
                }

                errorProvider1.SetError(txtDescuentos, "");
            }
            catch (FormatException) //esta excepción puede ocurrir cuando intenta convertir el descuento en double y no es un valor válido. En este caso no se toma el descuento.
            {

                errorProvider1.SetError(txtAbono, "Abono: el valor debe ser numérico.");
                txtVuelto.Text = "0";
            }
        }

        //Redefinido del padre
        protected override void procesar() //se encapsulo en un método para usar cuando se presiona Enter con los textBox
        {
            if (formularioValido())
            {
                try
                {
                    DialogResult result = MessageBox.Show("¿Desea confirmar el ingreso de la venta? ", "CONFIRMACION NUEVA VENTA", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                    if (result == DialogResult.Yes)
                    {
                        this.estEsperandoImpresion();

                        quitarFilasNoSeleccionadas();

                        agregarVenta();  //agrega un registro de venta a la tabla de Ventas

                        agregarProductoXVenta(); //agrega un registro de productosXVenta a esa tabla

                        decrementarStockProductos(); //decrementa el stock del producto vendidos

                        
                        incrementarCajaxVenta();

                        //Se muestra un mje de confirmación.
                        MessageBox.Show("Venta ingresada con exito!!!", "AVISO", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    }
                }


                catch (IndexOutOfRangeException)
                {

                }
                catch (Exception ex)
                {
                    //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                    MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    //Si llega a ocurrir algún error en estado agregar 
                    this.Close();
                }

            }
            else
            {
                informarExistenciaError();
            }

        }

               
        protected void quitarFilasNoSeleccionadas() //elimina aquellas filas que no se han seleccionado para vender
        {
            for (int i = 0; i < dgvVenta.RowCount ; i++)
            {
                if ((bool)dgvVenta.Rows[i].Cells[8].Value == false)
                {
                    dgvVenta.Rows.RemoveAt(i);

                    i--;
                }
            }
            
        }

        private void agregarVenta() //se da de alta una venta.
        {
           ventasTa .InsertQueryVenta (Convert.ToDateTime(this.obtenerFechaActual()), Math.Round(Convert.ToDecimal(this.txtSubtotal.Text), 2), Math.Round(Convert.ToDecimal(txtTotal.Text), 2), Math.Round(Convert.ToDecimal(txtDescuentos.Text), 2), true, this.turno, obtenerCodUsuarioActual(), this.txtObservacion.Text,Convert.ToDecimal ( obtenerCostoTotal ()), this.codCaja,cboFormaPago.SelectedItem .ToString (),lblDniCliente .Text  );
            
        }

        private void agregarProductoXVenta() //agrega un registro a la tabla ProductosXventa
        {
            int ultimaVenta = ventasTa.ScalarQueryUltimaVenta().Value; //obtiene la ultima venta; 
            ventasTa.FillByNroVenta(centerQuimDs.Ventas, ultimaVenta);

            foreach (DataGridViewRow row in dgvVenta.Rows)
            {

                productosXventaTa.Insert(ultimaVenta, row.Cells[1].Value.ToString(), row.Cells[2].Value.ToString(), Convert.ToDouble(row.Cells[3].Value), Convert.ToInt32(row.Cells[4].Value), Convert.ToDouble(row.Cells[5].Value), Math.Round(Convert.ToDouble(row.Cells[7].Value), 2), Math.Round(Convert.ToDouble(row.Cells[6].Value), 2), Convert.ToDouble(row.Cells[5].Value) * Convert.ToDouble(row.Cells[9].Value) + Convert.ToDouble(row.Cells[4].Value) * Convert.ToDouble(row.Cells[9].Value));
                //realizamos el movimiento
                movimientosxProductoAltaVenta(row.Cells[1].Value.ToString (), row.Cells[2].Value.ToString (), ultimaVenta, Convert.ToDouble (Convert.ToDouble(row.Cells[4].Value) + Convert.ToDouble(row.Cells[5].Value)));             
             }
        }

        private void decrementarStockProductos() //una vez vendido decrementa el stock de los productos, todos los productos se decrementa lo que se ha vendido a su propio stock, salvo que sea un producto 
        {                                         //disuelto para vender por granel, en este caso se debe descontar a la base el porcentaje de la cantidad que se vende.
            
            foreach (DataGridViewRow row in dgvVenta.Rows)
            {
                productosTa.FillByNombre(centerQuimDs.Productos, row.Cells[2].Value.ToString());

                double resgStock = centerQuimDs.Productos[0].stockActual;

                if ((centerQuimDs.Productos[0].tipo == "D") & (centerQuimDs.Productos[0].litrosEnvase == 0)) //es un producto disuelto para vender por granel, se descuenta de la base.
                {
                    Double multiplicadorPorcentual = Math.Round((centerQuimDs.Productos[0].porcentaje / 100), 2);  //si el porcentaje era 3, el multiplicador queda: 0,03.

                    Double cantidadDecrementar = Math.Round((Convert.ToDouble(row.Cells[5].Value) * multiplicadorPorcentual), 2);

                    string baseDescripcion = centerQuimDs.Productos[0].baseDescripcion.ToString();
                    
                    productosTa.FillByNombre(centerQuimDs.Productos, baseDescripcion); //en el if de abajo se decrementará del stock de la base.

                    
                    if (seDebeAjustar(cantidadDecrementar)) //valida si debe ajustar el stock.
                    {
                        //informarAjuste(cantidadDecrementar)
                        Double cantidadAjustada = 0;
                        cantidadAjustada = cantidadDecrementar - centerQuimDs.Productos[0].stockActual;
                        //MOVIMIENTO DE PRODUCTO CON cantidadAjustada.
                        
                        //ajustar
                        centerQuimDs.Productos[0].stockActual = 0;


                    }else //si no se debe ajustar solo se decrementa.
                    {
                        centerQuimDs.Productos[0].stockActual = centerQuimDs.Productos[0].stockActual - cantidadDecrementar;
                    
                    }


                
                }else //Es un producto terminado, base o disuelto para vender por cantidad
                {
                    if (Convert.ToDouble(row.Cells[4].Value) == 0) //si es un producto que se vende por granel
                    {
                        
                        if (seDebeAjustar(Convert.ToDouble(row.Cells[5].Value))) //valida si debe ajustar el stock.
                        {
                            //informarAjuste
                            Double cantidadAjustada = 0;
                            cantidadAjustada = Convert.ToDouble(row.Cells[5].Value) - centerQuimDs.Productos[0].stockActual;
                            //MOVIMIENTO DE PRODUCTO CON cantidadAjustada.
                        
                            //ajustar
                            centerQuimDs.Productos[0].stockActual = 0;
                            movimientoAjuste(centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, cantidadAjustada);


                        }else //si no se debe ajustar solo se decrementa.
                        {
                            centerQuimDs.Productos[0].stockActual = centerQuimDs.Productos[0].stockActual - Convert.ToDouble(row.Cells[5].Value); //se decrementa el stock de un producto vendido por granel.

                        }

                        
                    }
                    else//si es un producto que se vende por cantidad
                    {
                        if (seDebeAjustar(Convert.ToDouble(row.Cells[4].Value))) //valida si debe ajustar el stock., Si convierte el entero a real, ya que no hay problema.
                        {
                            //informarAjuste
                            Double cantidadAjustada = 0;
                            cantidadAjustada = Convert.ToInt32(row.Cells[4].Value) - centerQuimDs.Productos[0].stockActual;
                            //MOVIMIENTO DE PRODUCTO CON cantidadAjustada.

                            //ajustar
                            centerQuimDs.Productos[0].stockActual = 0;
                            movimientoAjuste(centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion,cantidadAjustada );


                        }
                        else //si no se debe ajustar solo se decrementa.
                        {
                            centerQuimDs.Productos[0].stockActual = centerQuimDs.Productos[0].stockActual - Convert.ToInt32(row.Cells[4].Value); //se decrementa el stock de un producto vendido por cantidad

                        }
                        
                    }
                }

                
                    productosTa.Update(centerQuimDs.Productos);
            }
        }

        private void movimientoAjuste(string unCodigo, string unaDescripcion, double unAjuste)
        {
            movimientosTa.InsertQueryMovimientosxProducto(unCodigo , unaDescripcion , Convert.ToDateTime(obtenerFechaActual()), "A", "Stock Negativo Venta Nº" + ventasTa.ScalarQueryUltimaVenta().ToString(), Convert.ToDecimal (unAjuste ));
        }

        private bool seDebeAjustar(double cantidadDecrementar)
        {
            return (centerQuimDs.Productos[0].stockActual - cantidadDecrementar) < 0;
        }



        private void incrementarCajaxVenta() //incrementa el campo Venta de la caja actual y el campo de cajaFinal
        {
            int ultimaVenta = ventasTa.ScalarQueryUltimaVenta().Value; //obtiene la ultima venta; 

            ventasTa.FillByNroVenta(centerQuimDs.Ventas, ultimaVenta);

            double totalGeneral = Math.Round(Convert.ToDouble(centerQuimDs.Ventas[0].totalGeneral),2);

            cajaTa.FillByNroCaja(centerQuimDs.Cajas, this.codCaja);

            centerQuimDs.Cajas[0].ventas += totalGeneral;


            procesarClientes(totalGeneral);

            cajaTa.Update(centerQuimDs.Cajas);
            
        }

        private void procesarClientes(double totalGeneral)
        {
            if (cboFormaPago.SelectedItem.ToString() == "Contado") //si es una venta al contado incrementa caja
            {
                centerQuimDs.Cajas[0].cajaFinal += totalGeneral;
            }
            else //si en una venta a cuenta corriente incrementa deudores y realiza el movimiento
            {
                centerQuimDs.Cajas[0].deudoresxVenta += totalGeneral;

                //incrementamos saldo de cliente y registramos movimiento

                clienteTa.FillByDni(ClienteDs.Clientes, lblDniCliente.Text);//buscamos cliente
                ClienteDs.Clientes[0].saldo += totalGeneral;//incrementamos saldo
                clienteTa.Update(ClienteDs.Clientes); //actualizamos base
                postTa.Fill(centerQuimDs.Post);

                movimientosClientesTa.InsertQueryMovimiento(lblDniCliente.Text, Convert.ToDateTime(obtenerFechaActual()), "Venta Nº " + ventasTa.ScalarQueryUltimaVenta().ToString() + " Post: " + centerQuimDs .Post [0].nombre, "Incremento Cta. Cte", Convert.ToDecimal(totalGeneral));
            }
        }

        private Double obtenerCostoTotal() //obtiene el costo de los productos vendidos. Usado en productosXventa.
        {
            Double costoTotal = 0;

            foreach (DataGridViewRow row in dgvVenta.Rows)
            {
                costoTotal += Convert.ToDouble(row.Cells[9].Value) * Convert.ToDouble(row.Cells[4].Value) + Convert.ToDouble(row.Cells[9].Value) * Convert.ToDouble(row.Cells[5].Value); //precioUniCosto*Cant + precioUnicosto*Kg.Ltrs.

            }

            return Math.Round(costoTotal, 2);

        }

        private int obtenerCodUsuarioActual()  //Dato necesario para el alta de venta
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getCodUsuario();
        }


        private string obtenerFechaActual()  //Dato necesario para el alta de venta
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getFechaActual();
        }

        protected override bool formularioValido()
        {
            validarGrilla();

            validarGrillaSinItems(); //valida que la grilla no se encuentre vacia o que contenga todos sus elementos sin seleccionar.

            validarDescuentos();

            validarFormaPago(); //si se quiere registrar una venta a cuenta corrientes, valida que exista un cliente y que tenga conexion a internet.

            
            if ((errorProvider1.GetError(dgvVenta) == "") & (errorProvider1.GetError(txtDescuentos) == "") & (errorProvider1.GetError(cboFormaPago)==""))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        protected void validarGrillaSinItems()
        {
            if (dgvVenta.Rows.Count == 0)
            {
                errorProvider1.SetError(dgvVenta, "Grilla: la grilla se encuentra vacia");
            
            }
            
            int cantidadTildados = 0;

            foreach (DataGridViewRow row in dgvVenta.Rows)
            {
                if ((bool)row.Cells[8].Value)
                {
                    cantidadTildados++;
                }
            }

            if (cantidadTildados == 0)
            {
                errorProvider1.SetError(dgvVenta, "Grilla: la grilla no contiene items seleccionado");
            }
        }

        protected void validarDescuentos() 
        {
            if (txtDescuentos.Text.Trim() == "")
            {
                errorProvider1.SetError(txtDescuentos, "Descuentos: el campo se encuentra vacio\n\n");
            }
            else
            {
                errorProvider1.SetError(txtDescuentos, new ValidarDatos().validarPorcentaje("Descuentos:", txtDescuentos.Text));
            }
        }

        private void validarFormaPago()  //metodo que valida, cuando se desee vender a cuenta corriente, que exista un cliente (distinto a Consumidor Final) y que tenga internet.
        {
            if (cboFormaPago.SelectedItem == null)
            {
                errorProvider1.SetError(cboFormaPago, "Debe seleccionar una forma de pago, para la venta actual.");
            }else
            {
                if (cboFormaPago.Text == "Contado")  //si la venta es de contado, no hace falta que tenga conexión a internet.
                {
                    errorProvider1.SetError(cboFormaPago, "");

                }
                else
                {
                    errorProvider1.SetError(cboFormaPago, this.validarExistenciaCliente() + this.validarConexionInternet());

                }
            }
            
            
        }

        private string validarExistenciaCliente() //valida que si se desea vender a cuenta corriente, exista un cliente diferente a CONSUMIDOR FINAL.
        {
            if (lblNombreCliente.Text == "CONSUMIDOR FINAL")
            {
                return "\nDebe seleccionar un cliente para realizar una venta a cuenta corriente.\n";
            }else
            {
                return "";
            }
        }
        
        private string validarConexionInternet()
        {
            try
            {
                System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry("www.google.com");

                return "";
            }
            catch (Exception)
            {
                return "Para realizar venta a cuenta corriente debe tener conexión a internet. \n Verifique la misma y vuelva a intentarlo.";

            }
        }

        


        private void btnNuevoPedido_Click(object sender, EventArgs e) //captura el evento click en boton pedido, con objetivo de generar un nuevo pedido.
        {
            this.validarGrilla(); //valida que la grilla donde existe selección, sea válida

            this.validarGrillaSinItems(); //valida que la grilla tenga fila o selecciones

            if (errorProvider1.GetError(dgvVenta) == "")  //si la grilla no tiene errores se procede a obtener el subtotal
            {
                DialogResult result = MessageBox.Show("¿Desea confirmar el ingreso del pedido? ", "CONFIRMACION NUEVO PEDIDO", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (result == DialogResult.Yes)
                {
                    try
                    {
                        agregarPedido();

                        agregarProductoXPedido();

                        quitarFilasSeleccionadas();

                        imprimirPedido();

                    }
                    catch (Exception ex)
                    {
                        //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                        MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                        //Si llega a ocurrir algún error en estado agregar 
                        this.Close();
                        
                    }
                }
                
            } else
            
            {
                MessageBox.Show(errorProvider1.GetError(dgvVenta), "INFORMES", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

        }
        
        private void agregarPedido() //agrega un registro de pedidos a la tabla
        {
            pedidoTa.Insert(Convert.ToDateTime(obtenerFechaActual()), "P", this.turno, obtenerCodUsuarioActual());
        }

        
        private void agregarProductoXPedido() //agrega un registro de productosXpedido a la tabla.
        {
            int ultimoPedido = pedidoTa.ScalarQueryUltimoPedido().Value; //obtiene el último pedido; 

            foreach (DataGridViewRow row in dgvVenta.Rows)
            {
                if ((bool)row.Cells[8].Value)
                {
                    productosXpedidoTa.Insert(ultimoPedido, row.Cells[1].Value.ToString(), row.Cells[2].Value.ToString(), Convert.ToDouble(row.Cells[3].Value), Convert.ToDouble(row.Cells[9].Value), Convert.ToInt32(row.Cells[4].Value), Math.Round(Convert.ToDouble(row.Cells[5].Value), 2), Math.Round(Convert.ToDouble(row.Cells[7].Value), 2), Math.Round(Convert.ToDouble(row.Cells[6].Value), 2));  

                }

            }
            
        }

        private void quitarFilasSeleccionadas() //elimina aquellas filas que se han seleccionado. Usado cuando se seleciona en nuevo pedido.
        {
            for (int i = 0; i < dgvVenta.RowCount ; i++)
            {
                if ((bool)dgvVenta.Rows[i].Cells[8].Value == true)
                {
                    dgvVenta.Rows.RemoveAt(i);

                    i--;
                }
            }
        }


        private void txtCodPedido_KeyDown(object sender, KeyEventArgs e) //captura el evento de presión enter sobre txtCodPedido
        {
            if ((e.KeyCode == Keys.Enter) & (this.estadoDelFormulario == "estEsperandoOperacion"))  //Si se presiona Enter y esta en el estado esperando operación con elementos en lstProductosDescripcion
            {
                eventoBusPedido();

            }
        }

        private void eventoBusPedido()
        {
            try
            {
                pedidoTa.FillByNroPedido(centerQuimDs.Pedidos,Convert.ToInt32(txtCodPedido.Text)); //se busca el pedido por el código


                if (centerQuimDs.Pedidos[0].estado == "P") //si existe y está pendiente de entrega
                {
                    productosXpedidoTa.FillByNroPedido(centerQuimDs.ProductosxPedido, Convert.ToInt32(txtCodPedido.Text)); //se busca todos los productos del pedido

                    for (int i = 0; i < centerQuimDs.ProductosxPedido.Rows.Count; i++) //se carga a la grilla todos los productos.
                    {
                        cargarPedidoEnGrilla(centerQuimDs.ProductosxPedido[i].descripcion,centerQuimDs.ProductosxPedido[i].unidades, centerQuimDs.ProductosxPedido[i].kgLts);
                    }

                    centerQuimDs.Pedidos[0].estado = "T"; //se coloca al pedido como terminado.

                    pedidoTa.Update(centerQuimDs.Pedidos); //se actualiza esta información en la base de datos

                    txtCodPedido.Text = ""; //se deja en blanco el txtCodPedido

                    txtCodBarra.Focus(); //se deja el foco en txtCodBarra.

                } else
                {
                    MessageBox.Show("El pedido especificado ya ha sido entregado", "INFORMES", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    txtCodPedido.Focus(); //se deja el foco en txtPedido ya que no existe.
                }
            }
            
            catch (IndexOutOfRangeException)
            {
                MessageBox.Show("El pedido especificado no existe", "INFORMES", MessageBoxButtons.OK, MessageBoxIcon.Information);

                txtCodPedido.Focus(); //se deja el foco en txtPedido ya que no existe.

            }
            catch (FormatException)
            {
                MessageBox.Show("El codigo ingresado debe ser numérico", "INFORMES", MessageBoxButtons.OK, MessageBoxIcon.Information);

                txtCodPedido.Focus(); //se deja el foco en txtPedido ya que no existe.
            }  
            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }
        }

        private void cargarPedidoEnGrilla(string unaDescripcion, int unaCantidad, double unKgLtrs) //método que carga el pedido en la grilla nuevamente.
        {
            //(ALE)HACER EL FILL O COMO LO LLAMES ACA ABAJO
            //ProductosTa.FillByProductos1(centerQuimDs,unCodBarra);
            productosTa.FillByNombre(centerQuimDs.Productos, unaDescripcion);
            
            if ((centerQuimDs.Productos[0].tipo == "T") || ((centerQuimDs.Productos[0].tipo == "D") & (centerQuimDs.Productos[0].litrosEnvase > 0))) //si el producto es terminado o disuelto para vender por cantidad. El stock es del producto actual. Se colorea la cantidad en gris y se pone solo lectura el kgLtrs.
                {
                    dgvVenta.Rows.Add(centerQuimDs.Productos[0].stockActual,centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, unaCantidad, unKgLtrs, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 1 y kiloLtrs 0

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[5].ReadOnly = true; //el kgLtrs se hace solo lectura

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[4].Style.BackColor = Color.LightGray; //cantidad es gris

                }
                else
                {
                    if (centerQuimDs.Productos[0].tipo == "B") //si el producto es base. El stock es del producto actual.
                    {
                        dgvVenta.Rows.Add(centerQuimDs.Productos[0].stockActual, centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, unaCantidad, unKgLtrs, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 0 y kiloLtrs 1

                    }
                    else //si el producto es disuelto para vender por granel. El stock es del producto base.
                    {
                        
                        string resgDescripcion = centerQuimDs.Productos[0].descripcion; //Para obtener el stock de la base, se debe reguardar la descripcion del producto actual, para luego volver a consultar y rellenar la fila.

                        string resgBaseDescripcion = centerQuimDs.Productos[0].baseDescripcion;

                        productosTa.FillByNombre(centerQuimDs.Productos, resgBaseDescripcion);

                        string stock = centerQuimDs.Productos[0].stockActual.ToString();

                        productosTa.FillByNombre(centerQuimDs.Productos, resgDescripcion);

                        dgvVenta.Rows.Add(stock, centerQuimDs.Productos[0].codProducto, centerQuimDs.Productos[0].descripcion, centerQuimDs.Productos[0].precioVenta, unaCantidad, unKgLtrs, 0, 0, true, centerQuimDs.Productos[0].precioCosto); //si el producto es para vender por cantidad, se setea unidad a 0 y kiloLtrs 1

                    }

                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[4].ReadOnly = true; //la cantidad se hace solo lectura
                    dgvVenta.Rows[dgvVenta.Rows.Count - 1].Cells[5].Style.BackColor = Color.LightGray; //kgLtrs es gris
                }

                verificarStock(); //formatea la fila correspondiente al producto ingresado, puede ser blanco, amarillo o rojo.
                                    //los prodcutos disueltos para venta por granel se colorea segun el estado de stock en su base.


                this.calcularSubTotalVenta();
        }

        private void btnBusPedido_Click(object sender, EventArgs e) //captura el evento de presion de boton en btnBusPedido.
        {
            eventoBusPedido();
        }

        protected override void presionTeclaF1(object sender, KeyEventArgs e)  //captura evento KeyDown sobre el forms
        {

            if (e.KeyCode == Keys.F6)
            {
                if (estadoDelFormulario == "estEsperandoImpresion")
                {
                    this.limpiarDatos();
                    this.estEsperandoOperacion();
                }

            }
            else
            {
                if (e.KeyCode == Keys.F2)
                {
                    if (estadoDelFormulario == "estEsperandoOperacion")
                    {
                        this.txtCodBarra.Focus();
                        this.txtCodBarra.Select();
                    }

                }
                else
                {
                    if (e.KeyCode == Keys.F4)
                    {
                        if (estadoDelFormulario == "estEsperandoOperacion")
                        {
                            this.txtAbono.Focus();
                            this.txtAbono.Select();
                        }

                    }
                    else
                    {
                        if (e.KeyCode == Keys.F5)
                        {
                            if (estadoDelFormulario == "estEsperandoOperacion")
                            {
                                this.procesar();
                            }

                        }
                    }
                }
            }


        }

        protected virtual void btnImprimir_Click(object sender, EventArgs e)
        {
            int ultimaVenta = ventasTa.ScalarQueryUltimaVenta().Value; //obtiene la ultima venta; 

            productosXventaTa.FillByNroVenta(centerQuimDs.ProductosxVenta, ultimaVenta);
            
            //Creamos una instancia de un objeto DataTable, y le hacemos que referencie a la tabla en CenterQuimDs.productoXventa
            DataTable unaDataTable = new DataTable();
            unaDataTable = centerQuimDs.ProductosxVenta;

            //creamos una instancia del tipo CrystalReports que habiamos creado y le asignamos a su crvVenta la tabla instanciada y parametros necesarios.
            crVenta unCrVenta = new crVenta();
            unCrVenta.SetDataSource(unaDataTable);

            //buscamos cliente
            clienteTa.FillByDni(ClienteDs.Clientes, lblDniCliente.Text);
            
            //buscamos post
            postTa.Fill(centerQuimDs.Post);

            unCrVenta.SetParameterValue("ventaCodValor","0000"+centerQuimDs.Ventas[0].nroVenta.ToString());
            unCrVenta.SetParameterValue("fechaValor", centerQuimDs.Ventas[0].fechaVenta.ToString("d"));
            unCrVenta.SetParameterValue("subtotalValor", centerQuimDs.Ventas[0].subTotalVenta.ToString());
            unCrVenta.SetParameterValue("descuentoValor", centerQuimDs.Ventas[0].importeDescuento.ToString());
            unCrVenta.SetParameterValue("totalGeneralValor", centerQuimDs.Ventas[0].totalGeneral.ToString());
            unCrVenta.SetParameterValue("postDireccion", centerQuimDs.Post[0].dirección.ToString());
            unCrVenta.SetParameterValue("postTelefono", centerQuimDs.Post[0].telefono.ToString());
           
            if (lblDniCliente.Text  == "0") //si no se indico el cliente
            {
                unCrVenta.SetParameterValue("unNombre", "CONSUMIDOR FINAL");
                unCrVenta.SetParameterValue("unaDireccion", " ");
            } else
            {
                unCrVenta.SetParameterValue("unNombre", ClienteDs .Clientes[0].apellidoyNombre .ToString ());
                unCrVenta.SetParameterValue("unaDireccion", ClienteDs .Clientes [0].direccion.ToString () + ". " + ClienteDs .Clientes [0].localidad .ToString () );
               
            }

            //creamos una instancia del frmReporteVenta y le asignamos a su CrystalReportViewer el CrystalReports seteado
            frmReporteVenta unFrmReporteVenta = new frmReporteVenta();
            unFrmReporteVenta.crvReporteVenta.ReportSource = unCrVenta;
            
            //mostramos el frmReporteVenta
            unFrmReporteVenta.ShowDialog();

        }

        private void imprimirPedido()
        {
            int ultimoPedido = pedidoTa.ScalarQueryUltimoPedido().Value;
            productosXpedidoTa.FillByNroPedido(centerQuimDs.ProductosxPedido, ultimoPedido);
            pedidoTa .FillByNroPedido (centerQuimDs .Pedidos ,ultimoPedido );

            //Creamos una instancia de un objeto DataTable, y le hacemos que referencie a la tabla en CenterQuimDs.productoXPedido
            DataTable unaDataTable = new DataTable();
            unaDataTable = centerQuimDs.ProductosxPedido;

            //creamos una instancia del tipo CrystalReports que habiamos creado y le asignamos a su crvVenta la tabla instanciada y parametros necesarios.
            crPedido  unCrPedido = new crPedido ();
            unCrPedido.SetDataSource(unaDataTable);

            unCrPedido.SetParameterValue("fechaValor", centerQuimDs.Pedidos[0].fechaPedido.ToString("d"));
            unCrPedido.SetParameterValue("turnoValor", centerQuimDs.Pedidos[0].turno);
            //unCrPedido.SetParameterValue("subtotalValor", txtSubtotal.Text.ToString ());
            //unCrPedido.SetParameterValue("descuentosValor", txtDescuentos.Text.ToString ());
            //unCrPedido.SetParameterValue("totalValor", txtTotal.Text.ToString ());

            //creamos una instancia del frmReportePedido y le asignamos a su CrystalReportViewer el CrystalReports seteado
            frmReportePedido unFrmReportePedido = new frmReportePedido();
            unFrmReportePedido.crvPedido .ReportSource = unCrPedido ;

            //mostramos el frmReporteVenta
            unFrmReportePedido.ShowDialog();


        }

        private void movimientosxProductoAltaVenta(string codigo, string descripcion,int venta, double cantidad)
        {
            movimientosTa.InsertQueryMovimientosxProducto(codigo, descripcion, Convert.ToDateTime(obtenerFechaActual()), "B", "Venta Nº: " + venta.ToString(), Convert.ToDecimal(cantidad));
        }

        private void btnBuscarCliente_Click(object sender, EventArgs e) //metodo capturador del evento click sobre el boton BuscarCliente. Desplega un formulario para elegir un cliente.
        {
            frmBuscarClientes unFrmBuscarCliente = new frmBuscarClientes(this); //Se crea el frmBuscarCliente para abrir.

            unFrmBuscarCliente.ShowDialog(); //Se muestra en forma modal.
            
        }

        public void cargarCliente(string unDni, string unApellidoNombre, string unDescuento) 
        {
            this.lblDniCliente.Text = unDni;
            this.lblNombreCliente.Text = unApellidoNombre;
            this.txtDescuentos.Text = unDescuento;
            this.cboFormaPago.SelectedIndex = -1;

        }


    }
}
